package com.gzhryc.shared_device.oem.code.member.services;

import java.sql.SQLException;
import java.util.Date;
import java.util.List;

import com.gzhryc.common.StringTools;
import com.gzhryc.common.exceptions.LogicException;
import com.gzhryc.common.logging.Logger;
import com.gzhryc.jdbc.Conditions;
import com.gzhryc.jdbc.JdbcSession;
import com.gzhryc.jdbc.MultiDBTools;
import com.gzhryc.shared_device.base.enums.EPayType;
import com.gzhryc.shared_device.base.enums.ERefundState;
import com.gzhryc.shared_device.base.models.OperateInfo;
import com.gzhryc.shared_device.common.payment.dao.db.AliRefundOrder;
import com.gzhryc.shared_device.common.payment.dao.db.AlipayOrder;
import com.gzhryc.shared_device.common.payment.dao.db.WXPayOrder;
import com.gzhryc.shared_device.common.payment.dao.db.WXRefundOrder;
import com.gzhryc.shared_device.common.payment.services.AliRefundOrderService;
import com.gzhryc.shared_device.common.payment.services.AlipayOrderService;
import com.gzhryc.shared_device.common.payment.services.WXPayOrderService;
import com.gzhryc.shared_device.common.payment.services.WXRefundOrderService;
import com.gzhryc.shared_device.oem.code.member.dao.MemberRechargeRefundOrderDao;
import com.gzhryc.shared_device.oem.code.member.dao.db.MemberRechargeOrder;
import com.gzhryc.shared_device.oem.code.member.dao.db.MemberRechargeRefundOrder;

public class MemberRechargeRefundOrderService {

    static Logger log = Logger.getLogger(MemberRechargeRefundOrderService.class);

    public static MemberRechargeRefundOrderService self() {
        return MultiDBTools.getService(MemberRechargeRefundOrderService.class, true);
    }

    public static MemberRechargeRefundOrderService self(Date date) {
        return MultiDBTools.getService(MemberRechargeRefundOrderService.class, date);
    }

    
    public static MemberRechargeRefundOrderService self(String jdbcKey,Date date) {
        return MultiDBTools.getService(jdbcKey, MemberRechargeRefundOrderService.class, date);
    }

    MemberRechargeRefundOrderDao dao;

    public MemberRechargeRefundOrderService(String jdbcKey) {
        dao = new MemberRechargeRefundOrderDao(jdbcKey);
    }
    
    public MemberRechargeRefundOrderService(String jdbcKey,Date date) {
        dao = new MemberRechargeRefundOrderDao(jdbcKey,date);
    }

    public List<MemberRechargeRefundOrder> findByTransferTradeNo(String transferTradeNo){
        if(StringTools.isNotBlank(transferTradeNo)){
            Conditions conditions = new Conditions(MemberRechargeRefundOrder.class);
            conditions.and().is("transferTradeNo",transferTradeNo);

            try {
                return dao.findByCondition(conditions);
            } catch (SQLException e) {
                log.error(e.getMessage(),e);
            }
        }
        return null;
    }

    public MemberRechargeRefundOrder getByTradeNo(String tradeNo){
        try {
            return dao.getById(tradeNo);
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return null;
    }

    public MemberRechargeRefundOrder createRefundOrder(MemberRechargeOrder order, String transferTradeNo, Integer refundMoney,String operateNote) throws LogicException {
        if (order != null && StringTools.isNotBlank(transferTradeNo) && refundMoney != null) {
            if(EPayType.WXPay.index().equals(order.getPayType())){
                WXPayOrder wxPayOrder = WXPayOrderService.self(order.getCreateDate()).getByTradeNo(order.getPayTradeNo());
                if(wxPayOrder != null) {
                    WXRefundOrder wxRefundOrder = WXRefundOrderService.self(order.getCreateDate()).createRefundOrder(wxPayOrder,refundMoney,operateNote);
                    if(wxRefundOrder != null){
                        MemberRechargeRefundOrder refundOrder = new MemberRechargeRefundOrder();
                        refundOrder.setTradeNo(wxRefundOrder.getTradeNo());
                        refundOrder.setTransferTradeNo(transferTradeNo);
                        refundOrder.setRechargeTradeNo(order.getTradeNo());
                        refundOrder.setRefundMoney(refundMoney);
                        refundOrder.setMemberId(order.getMemberId());
                        refundOrder.setPayType(order.getPayType());
                        refundOrder.setRefundMoney(refundMoney);
                        refundOrder.setCreateDate(order.getCreateDate());

                        JdbcSession.begin();
                        try {
                            if(MemberRechargeOrderService.self(order.getCreateDate()).toOperateRefundLock(order.getTradeNo())){
                                if (dao.insert(refundOrder) > 0) {
                                    JdbcSession.commit();
                                    return refundOrder;
                                }
                            }
                        } catch (SQLException e) {
                            log.error(e.getMessage(), e);
                        }finally {
                            JdbcSession.end();
                        }
                    }
                }
            }else if(EPayType.Alipay.index().equals(order.getPayType())) {
            	AlipayOrder alipayOrder = AlipayOrderService.self(order.getCreateDate()).getByTradeNo(order.getPayTradeNo());
                if(alipayOrder != null) {
                    AliRefundOrder aliRefundOrder = AliRefundOrderService.self(order.getCreateDate()).createRefundOrder(alipayOrder,refundMoney,operateNote);
                    if(aliRefundOrder != null){
                        MemberRechargeRefundOrder refundOrder = new MemberRechargeRefundOrder();
                        refundOrder.setTradeNo(aliRefundOrder.getTradeNo());
                        refundOrder.setTransferTradeNo(transferTradeNo);
                        refundOrder.setRechargeTradeNo(order.getTradeNo());
                        refundOrder.setRefundMoney(refundMoney);
                        refundOrder.setMemberId(order.getMemberId());
                        refundOrder.setPayType(order.getPayType());
                        refundOrder.setRefundMoney(refundMoney);
                        refundOrder.setCreateDate(order.getCreateDate());

                        JdbcSession.begin();
                        try {
                            if(MemberRechargeOrderService.self(order.getCreateDate()).toOperateRefundLock(order.getTradeNo())){
                                if (dao.insert(refundOrder) > 0) {
                                    JdbcSession.commit();
                                    return refundOrder;
                                }
                            }
                        } catch (SQLException e) {
                            log.error(e.getMessage(), e);
                        }finally {
                            JdbcSession.end();
                        }
                    }
                }
            }
        }
        return null;
    }

    public int refundResult(WXRefundOrder wxRefundOrder,OperateInfo operateInfo){
        if(wxRefundOrder != null) {
            MemberRechargeRefundOrder refundOrder = getByTradeNo(wxRefundOrder.getTradeNo());
            if (refundOrder != null) {
                if(ERefundState.Success.index().equals(refundOrder.getRefundState())
                        || ERefundState.Fail.index().equals(refundOrder.getRefundState())){
                    return 1;     //已处理过
                }

                Conditions conditions = new Conditions(MemberRechargeRefundOrder.class);
                conditions.and().is("tradeNo",refundOrder.getTradeNo());
                conditions.and().is("refundState",refundOrder.getRefundState());

                MemberRechargeRefundOrder updateEntity = new MemberRechargeRefundOrder();
                updateEntity.setRefundState(wxRefundOrder.getRefundStatus());
                updateEntity.setRefundDate(new Date());

                boolean flag = false;
                try {
                    if(dao.updateNotNull(updateEntity,conditions) > 0){
                        flag = true;
                    }
                } catch (SQLException e) {
                    log.error(e.getMessage(),e);
                }

                if(flag && ERefundState.Success.index().equals(updateEntity.getRefundState())){
                    MemberTransferMoneyOrderService.self().rechargeOrderRefundCheckFinish(refundOrder.getTransferTradeNo()
                    		,operateInfo);
                    return 1;
                }
                return 2;       //代表进行处理
            }
        }
        return -1;
    }
    
    public int refundResult(AliRefundOrder aliRefundOrder,OperateInfo operateInfo){
        if(aliRefundOrder != null) {
            MemberRechargeRefundOrder refundOrder = getByTradeNo(aliRefundOrder.getTradeNo());
            if (refundOrder != null) {
                if(ERefundState.Success.index().equals(refundOrder.getRefundState())
                        || ERefundState.Fail.index().equals(refundOrder.getRefundState())){
                    return 1;     //已处理过
                }

                Conditions conditions = new Conditions(MemberRechargeRefundOrder.class);
                conditions.and().is("tradeNo",refundOrder.getTradeNo());
                conditions.and().is("refundState",refundOrder.getRefundState());

                MemberRechargeRefundOrder updateEntity = new MemberRechargeRefundOrder();
                updateEntity.setRefundState(aliRefundOrder.getRefundStatus());
                updateEntity.setRefundDate(new Date());

                boolean flag = false;
                try {
                    if(dao.updateNotNull(updateEntity,conditions) > 0){
                        flag = true;
                    }
                } catch (SQLException e) {
                    log.error(e.getMessage(),e);
                }

                if(flag && ERefundState.Success.index().equals(updateEntity.getRefundState())){
                    MemberTransferMoneyOrderService.self().rechargeOrderRefundCheckFinish(refundOrder.getTransferTradeNo()
                    		,operateInfo);
                    return 1;
                }
                return 2;       //代表进行处理
            }
        }
        return -1;
    }
}
